/****************************************************************************
*                                                                           *
* Copyright (c) 2009 Nuvoton Electronics Corp. All rights reserved.         *
*                                                                           *
*****************************************************************************/

/****************************************************************************
* FILENAME
*   diag_pwm.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The PWM test program
*
* DATA STRUCTURES
*   None
*
* FUNCTIONS
*   PWM_Item
*   PWM_Test
*   PWM_TestAll
*   PWM_Timer
*   PWM_TimerDZ
*
* HISTORY
*   2007-11-23  Ver 1.0
*
* REMARK
*   None
****************************************************************************/
//System Library
#include "wblib.h"

//NON OS Library
#include "NUC900_pwm.h"

//Function Definition
VOID PWM_Timer(INT nTimerNum);
VOID diag_pwm(VOID);


/****************************************************************************
* FUNCTION
*   diag_pwm
*
* DESCRIPTION
*   The PWM timer test function which includs all PWM timer
*
* CALLED BY
*   main
*
* INPUTS
*   None
*
* OUTPUTS
*   None
*
* HISTORY
*   NAME        DATE        REMARKS
*   NS21 WTLiu  2006-04-04  Created initial version
*
* REMARK
*     None
****************************************************************************/
VOID diag_pwm(VOID)
{
    PWM_Timer(PWM_TIMER0);
    PWM_Timer(PWM_TIMER1);
    PWM_Timer(PWM_TIMER2);
    PWM_Timer(PWM_TIMER3);
}

/****************************************************************************
* FUNCTION
*   PWM_Timer
*
* DESCRIPTION
*   The PWM timer test function
*
* CALLED BY
*   PWM_Test
*
* INPUTS
*   nTimerNum
*
* OUTPUTS
*   None
*
* HISTORY
*   NAME        DATE        REMARKS
*   NS21 WTLiu  2005-12-23  Created initial version
*
* REMARK
*     None
****************************************************************************/
VOID PWM_Timer(INT nTimerNum)
{
    typeTIMERVALUE timervalue;
    typePWMSTATUS PWMSTATUS;
    INT nLoop = 0;
    INT nStatus = 0;
    INT nInterruptInterval = 0;

    PWMSTATUS.PDR = 0;
    PWMSTATUS.InterruptFlag = FALSE;
    sysprintf("\nStart PWM Timer %d test:\n", nTimerNum);

    pwmInit();
    pwmOpen(nTimerNum);

    // Change PWM Timer setting
    pwmIoctl(nTimerNum, SET_CSR, 0, CSRD16);
    pwmIoctl(nTimerNum, SET_CP, 0, 49);
    pwmIoctl(nTimerNum, SET_DZI, 0, 0);
    pwmIoctl(nTimerNum, SET_INVERTER, 0, PWM_INVOFF);
    pwmIoctl(nTimerNum, SET_MODE, 0, PWM_ONESHOT);
    pwmIoctl(nTimerNum, DISABLE_DZ_GENERATOR, 0, 0);
    pwmIoctl(nTimerNum, ENABLE_PWMGPIOOUTPUT, 0, 0);


    #ifdef DEBUG_TEST_MODE
    timervalue.field.cnr = 1000;
    #else
    timervalue.field.cnr = 59999;
    #endif

    timervalue.field.cmr = 4999;
    pwmWrite(nTimerNum, (PUCHAR)(&timervalue), sizeof(timervalue));

    sysprintf("PWM Timer%d one shot mode test\n", nTimerNum);
    sysprintf("PWM Timer interrupt will occur after a few second");

    //Start PWM Timer
    pwmIoctl(nTimerNum, START_PWMTIMER, 0, 0);

    while(1)
    {
        nLoop++;
        if(nLoop%200000 == 0)
        {
            sysprintf(".");
        }
        nStatus = pwmRead(nTimerNum, (PUCHAR)&PWMSTATUS, sizeof(PWMSTATUS));
        if(nStatus != Successful)
        {
            sysprintf("PWM read error, ERR CODE:%d", nStatus);
            pwmClose(nTimerNum);
            return;
        }
        if(PWMSTATUS.InterruptFlag == TRUE)
        {
            sysprintf("\n\nPWM Timer interrupt occurred!\n\n");
            break;
        }
    }

    // Change PWM Timer setting
    pwmIoctl(nTimerNum, SET_CSR, 0, CSRD16);
    pwmIoctl(nTimerNum, SET_CP, 0, 49);
    pwmIoctl(nTimerNum, SET_DZI, 0, 0);
    pwmIoctl(nTimerNum, SET_INVERTER, 0, PWM_INVOFF);
    pwmIoctl(nTimerNum, SET_MODE, 0, PWM_TOGGLE);
    pwmIoctl(nTimerNum, DISABLE_DZ_GENERATOR, 0, 0);
    pwmIoctl(nTimerNum, ENABLE_PWMGPIOOUTPUT, 0, 0);

    #ifdef DEBUG_TEST_MODE
    nInterruptInterval = 1000;
    #else
    nInterruptInterval = 30000;
    #endif

    timervalue.field.cnr = nInterruptInterval;
    timervalue.field.cmr = 4999;
    pwmWrite(nTimerNum, (PUCHAR)(&timervalue), sizeof(timervalue));

    sysprintf("PWM Timer%d toggle mode test\n", nTimerNum);
    sysprintf("PWM Timer interrupt interval will decrease gradually\n");

    //Start PWM Timer
    pwmIoctl(nTimerNum, START_PWMTIMER, 0, 0);
    nLoop = 0;
    while(1)
    {
        nStatus = pwmRead(nTimerNum, (PUCHAR)&PWMSTATUS, sizeof(PWMSTATUS));
        if(nStatus != Successful)
        {
            sysprintf("PWM read error, ERR CODE:%d", nStatus);
            pwmClose(nTimerNum);
            return;
        }
        if(PWMSTATUS.InterruptFlag == TRUE)
        {
            sysprintf("PWM Timer interrupt [%d], CNR:%d\n", nLoop, nInterruptInterval);
            nInterruptInterval /= 2;
            timervalue.field.cnr = nInterruptInterval;
            timervalue.field.cmr = 4999;
            pwmWrite(nTimerNum, (PUCHAR)(&timervalue), sizeof(timervalue));
            nLoop++;
            #ifdef DEBUG_TEST_MODE
            if(nLoop == 3)
            #else
            if(nLoop == 10)
            #endif
            {
                break;
            }
        }
    }
    pwmIoctl(nTimerNum, STOP_PWMTIMER, 0, 0);
    pwmClose(nTimerNum);
    sysprintf("\nPWM Timer %d test finish\n", nTimerNum);
    return;
}

